﻿// <copyright file="ClientSession.cs" company="Ecole Normale Supérieure">
// Released under GPLv2
// </copyright>
// <summary>Contains a ClientSession a session per tab/browser/...</summary>

namespace Sqwarea.Web.Misc
{
    using System;
    using System.Collections.Generic;
    using System.Drawing;
    using System.Linq;
    using System.Web;

    /// <summary>
    /// A session per tab/browser/F5 refresh/...
    /// Different from ASP.Net session created per browser only.
    /// This session is normally saved in a dictionnary in the ASP.Net session.
    /// </summary>
    public class ClientSession
    {
        /// <summary>
        /// Gets or sets number of minutes for a session to expire
        /// </summary>
        private const double ExpireMinutes = 5;

        /// <summary>
        /// Initializes a new instance of the ClientSession class.
        /// </summary>
        public ClientSession()
        {
            LogsTimestamp = new DateTimeOffset(1970, 1, 1, 0, 0, 0, TimeSpan.Zero);
            SquaresETags = new Dictionary<Point, string>();
            LastUsed = DateTimeOffset.Now;
        }

        /// <summary>
        /// Gets or sets ETags of all viewed squares
        /// </summary>
        public Dictionary<Point, string> SquaresETags { get; set; }

        /// <summary>
        /// Gets or sets last time logs have been viewed
        /// </summary>
        public DateTimeOffset LogsTimestamp { get; set; }

        /// <summary>
        /// Gets or sets last time this session has been used
        /// </summary>
        public DateTimeOffset LastUsed { get; set; }

        /// <summary>
        /// Remove all expired sessions in sessions
        /// </summary>
        /// <param name="sessions">The dictionary of sessions</param>
        public static void CleanClientSessions(IDictionary<string, ClientSession> sessions)
        {
            var expiredSessions = sessions
                .Where(session => DateTimeOffset.Now.Subtract(session.Value.LastUsed).TotalMinutes >= ExpireMinutes)
                .Select(session => session.Key)
                .ToList();

            foreach (var session in expiredSessions)
            {
                sessions.Remove(session);
            }
        }

        /// <summary>
        /// Update the last used time.
        /// Should be called at each request of server.
        /// </summary>
        public void UpdateLastUsed()
        {
            LastUsed = DateTimeOffset.Now;
        }
    }
}
